/**
 * ControladoraBDReportes.java
 */

 /**
 *  AdSec: Administrador de Secundarias
 *  Copyright (C) 2009 Daniela Ramírez Chaves (dannyrch@gmail.com)
 *  Copyright (C) 2009 Leonel Salazar Valverde (leo87sv@gmail.com)
 *
 *  This file is part of AdSec.
 *  AdSec is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  AdSec is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with AdSec.  If not, see <http://www.gnu.org/licenses/>.
 */

package adsec.datos;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedList;
import adsec.entidades.Materia;
import adsec.entidades.MateriaCursada;
import adsec.entidades.entidadesReportes.ListaReporteNotasHogar;
import adsec.entidades.entidadesReportes.ReporteAsistenciaPeriodo;
import adsec.entidades.entidadesReportes.ReporteMateriaAplazada;
import adsec.entidades.entidadesReportes.ReporteNotasHogar;


public class ControladoraBDReportes {
    private Connection conexion;
    private AdministradorConexion adminConexion;

    public ControladoraBDReportes(){
         adminConexion = AdministradorConexion.getInstancia();
    }

    public ListaReporteNotasHogar consultarReporteNotas(int anio, String cedulaEstudiante, int tipoMateria){
        ListaReporteNotasHogar reportes = null;
        conexion = adminConexion.getConexion();
        if(conexion != null){
            CallableStatement procedimiento = this.spConsultarReportesNotas(conexion,anio, cedulaEstudiante, tipoMateria);
            if(procedimiento != null){
                try{
                    procedimiento.execute();
                    ResultSet resultado = procedimiento.getResultSet();
                    reportes = crearListaReportes(resultado, anio, cedulaEstudiante, conexion);
                }catch(SQLException e){
                    e.printStackTrace();
                }
            }
        }
        adminConexion.cerrarConexion();
        return reportes;
    }

    private void consultarInfomarcionAnual(Connection conexion, String cedulaEstudiante, ReporteNotasHogar reporte){
        CallableStatement procedimiento = spConsultarInformacionAnual(conexion, reporte.getAnio(), reporte.getNivel(),
                                                                reporte.getNum_seccion(), cedulaEstudiante,
                                                                reporte.getIdMateria(), reporte.getIdMateriaCursada());
        if(procedimiento != null){
            try{
                procedimiento.execute();
                ResultSet resultado = procedimiento.getResultSet();
                if(resultado.next()){
                    reporte.setNotaFinal(resultado.getDouble(ReporteNotasHogar.notaFinalNC));
                    reporte.setNotaAnual(resultado.getDouble(ReporteNotasHogar.notaAnualNC));
                    reporte.setCondicion(resultado.getBoolean(ReporteNotasHogar.aprobadoNC));
                }
            }catch(SQLException e){
                e.printStackTrace();
            }
        }
    }

    public LinkedList<ReporteMateriaAplazada> consultarMateriasAplazadas(int anio, String cedulaEstudiante){
        LinkedList<ReporteMateriaAplazada> materiasAplazadas = new LinkedList<ReporteMateriaAplazada>();
        conexion = adminConexion.getConexion();
        if(conexion != null){
            CallableStatement procedimiento = this.spConsultarMateriasAplazadas(conexion,anio, cedulaEstudiante);
            if(procedimiento != null){
                try{
                    procedimiento.execute();
                    ResultSet resultado = procedimiento.getResultSet();
                    while(resultado.next()){
                        ReporteMateriaAplazada materiaAplazada = crearReporteMateriaAplazada(resultado);
                        materiasAplazadas.add(materiaAplazada);
                    }
                }catch(SQLException e){
                    e.printStackTrace();
                }
            }
        }
        adminConexion.cerrarConexion();
        return materiasAplazadas;
    }

    public LinkedList<ReporteAsistenciaPeriodo> consultarAsistenciaPeriodo(int anio, String cedulaEstudiante){
        LinkedList<ReporteAsistenciaPeriodo> reportes = new LinkedList<ReporteAsistenciaPeriodo>();
        conexion = adminConexion.getConexion();
        if(conexion != null){
            CallableStatement procedimiento = this.spConsultarAsistenciaPeriodo(conexion,anio, cedulaEstudiante);
            if(procedimiento != null){
                try{
                    procedimiento.execute();
                    ResultSet resultado = procedimiento.getResultSet();
                    while(resultado.next()){
                        ReporteAsistenciaPeriodo reporte = this.crearReporteAsistenciaPeriodo(resultado);
                        reportes.add(reporte);
                    }
                }catch(SQLException e){
                    e.printStackTrace();
                }
            }
        }
        adminConexion.cerrarConexion();
        return reportes;
    }

    public int consultarNivelActualEstudiante(int anio, String cedula){
        int nivel = 0;
        conexion = adminConexion.getConexion();
        if(conexion != null){
            CallableStatement procedimiento = this.spConsultarNivelActualEstudiante(anio, cedula);
            if(procedimiento != null){
                try{
                    procedimiento.execute();
                    ResultSet resultado = procedimiento.getResultSet();
                    if(resultado.next()){
                        nivel = resultado.getInt(ReporteNotasHogar.nivelNC);
                    }
                }catch(SQLException e){
                    e.printStackTrace();
                }
            }
        }
        return nivel;
    }

    private CallableStatement spConsultarReportesNotas(Connection conexion,int anio, String cedulaEstudiante, int tipoMateria){
        CallableStatement procedimiento = null;
        try {
            procedimiento = conexion.prepareCall("CALL consultarReporteNotas" + UtilidadesCapaDatos.agregarParametros(3),
                    ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            procedimiento.setInt(ReporteNotasHogar.anioNC + "_p", anio);
            procedimiento.setString(ReporteNotasHogar.cedulaNC + "_p", cedulaEstudiante);
            procedimiento.setInt(Materia.tipoMateriaNC + "_p", tipoMateria);
        } catch (SQLException sqlException) {
            sqlException.printStackTrace();
        }
        return procedimiento;
    }

    private CallableStatement spConsultarInformacionAnual(Connection conexion, int anio, int nivel, int seccion,
                                                    String cedula,int idMateria, int idMateriaCursada){
        CallableStatement procedimiento = null;
        try {
            procedimiento = conexion.prepareCall("CALL consultarInformacionAnual" + UtilidadesCapaDatos.agregarParametros(6),
                    ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            procedimiento.setInt(ReporteNotasHogar.anioNC + "_p", anio);
            procedimiento.setInt(ReporteNotasHogar.nivelNC + "_p", nivel);
            procedimiento.setInt(ReporteNotasHogar.seccionNC + "_p", seccion);
            procedimiento.setString(ReporteNotasHogar.cedulaNC + "_p", cedula);
            procedimiento.setInt(ReporteNotasHogar.idMateriaNC + "_p", idMateria);
            procedimiento.setInt(ReporteNotasHogar.idMateriaCursadaNC + "_p", idMateriaCursada);
        } catch (SQLException sqlException) {
            sqlException.printStackTrace();
        }
        return procedimiento;
    }

    private CallableStatement spConsultarMateriasAplazadas(Connection conexion,int anio, String cedulaEstudiante){
        CallableStatement procedimiento = null;
        try {
            procedimiento = conexion.prepareCall("CALL consultarMateriaAplazadas" + UtilidadesCapaDatos.agregarParametros(2),
                    ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            procedimiento.setInt(ReporteNotasHogar.anioNC + "_p", anio);
            procedimiento.setString(ReporteNotasHogar.cedulaNC + "_p", cedulaEstudiante);
        } catch (SQLException sqlException) {
            sqlException.printStackTrace();
        }
        return procedimiento;
    }

    private CallableStatement spConsultarAsistenciaPeriodo(Connection conexion,int anio, String cedulaEstudiante){
        CallableStatement procedimiento = null;
        try {
            procedimiento = conexion.prepareCall("CALL consultarAsistenciaPeriodo" + UtilidadesCapaDatos.agregarParametros(2),
                    ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            procedimiento.setInt(ReporteAsistenciaPeriodo.anioNC + "_p", anio);
            procedimiento.setString(ReporteAsistenciaPeriodo.cedulaNC + "_p", cedulaEstudiante);
        } catch (SQLException sqlException) {
            sqlException.printStackTrace();
        }
        return procedimiento;
    }

    private CallableStatement spConsultarNivelActualEstudiante(int anio, String cedula){
        CallableStatement procedimiento = null;
        try{
            procedimiento = conexion.prepareCall("CALL consultarNivelActualEstudiante" +  UtilidadesCapaDatos.agregarParametros(2),
                    ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            procedimiento.setInt(ReporteNotasHogar.anioNC + "_p", anio);
            procedimiento.setString(ReporteNotasHogar.cedulaNC + "_p", cedula);
        }catch(SQLException sqlException){
            sqlException.printStackTrace();
        }
        return procedimiento;
    }

    private ListaReporteNotasHogar crearListaReportes(ResultSet resultado, int anio, String cedula, Connection conexion) throws SQLException{
        ListaReporteNotasHogar reportes = new ListaReporteNotasHogar();
        int maxPeriodo = 0;
        while(resultado.next()){
            ReporteNotasHogar reporte = new ReporteNotasHogar();
            reporte.setAnio(anio);
            reporte.setNivel(resultado.getInt(ReporteNotasHogar.nivelNC));
            reporte.setNum_seccion(resultado.getInt(ReporteNotasHogar.seccionNC));
            reporte.setNombreMateria(resultado.getString(ReporteNotasHogar.nombreMateriaNC));
            reporte.setNum_periodo(resultado.getInt(ReporteNotasHogar.periodoNC));
            int cantidadPeriodos = resultado.getInt(MateriaCursada.cantidadPeriodosNC);
            maxPeriodo = cantidadPeriodos > maxPeriodo ? cantidadPeriodos : maxPeriodo;
            reporte.setIdMateria(resultado.getInt(ReporteNotasHogar.idMateriaNC));
            reporte.setIdMateriaCursada(resultado.getInt(ReporteNotasHogar.idMateriaCursadaNC));
            reporte.setNotaMinima(resultado.getDouble(ReporteNotasHogar.notaMinimaNC));
            reporte.setNota(resultado.getDouble(ReporteNotasHogar.notaNC));
            this.consultarInfomarcionAnual(conexion, cedula, reporte);
            reporte.setTipoMatricula(resultado.getInt(ReporteNotasHogar.tipoMatriculaNC));
            reporte.setPorcentaje(resultado.getDouble(ReporteNotasHogar.porcentajeNC));
            reportes.agregarReporteNota(reporte);
        }
        reportes.setCantidadPeriodos(maxPeriodo);
        return reportes;
    }

    private ReporteMateriaAplazada crearReporteMateriaAplazada(ResultSet resultado) throws SQLException{
        ReporteMateriaAplazada reporte = new ReporteMateriaAplazada();
        reporte.setNivel(resultado.getInt(ReporteMateriaAplazada.nivelNC));
        reporte.setNum_seccion(resultado.getInt(ReporteMateriaAplazada.seccionNC));
        reporte.setNombreMateria(resultado.getString(ReporteMateriaAplazada.nombreMateriaNC));
        reporte.setNotaConv1(resultado.getDouble(ReporteMateriaAplazada.nota_conv1NC));
        reporte.setEstado_conv1(resultado.getString(ReporteMateriaAplazada.estado_conv1NC));
        reporte.setNotaConv2(resultado.getDouble(ReporteMateriaAplazada.nota_conv2NC));
        reporte.setEstado_conv2(resultado.getString(ReporteMateriaAplazada.estado_conv2NC));
        return reporte;
    }

    private ReporteAsistenciaPeriodo crearReporteAsistenciaPeriodo(ResultSet resultado) throws SQLException{
        ReporteAsistenciaPeriodo reporte = new ReporteAsistenciaPeriodo();
        reporte.setPeriodo(resultado.getInt(ReporteAsistenciaPeriodo.periodoNC));
        reporte.setAusenciasJustificadas(resultado.getInt(ReporteAsistenciaPeriodo.ausenciasJustificadasNC));
        reporte.setAusenciasInjustificadas(resultado.getInt(ReporteAsistenciaPeriodo.ausenciasInjustificadasNC));
        reporte.setEscapadas(resultado.getInt(ReporteAsistenciaPeriodo.escapadasNC));
        reporte.setTardias(resultado.getInt(ReporteAsistenciaPeriodo.tardiasNC));
        return reporte;
    }
}
